package com.example.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.common.Result;
import com.example.entity.Package;
import com.example.exception.CustomerException;
import com.example.mapper.PackageMapper;
import com.example.service.GeneratorService;
import com.example.service.PackageService;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/package")
public class PackageController {

    @Resource
    PackageService packageService;

    @Resource
    private PackageMapper packageMapper;

    @Resource
    private GeneratorService generatorService;

    @PostMapping("/add")
    public Result add(@RequestBody Package pack) { // @RequestBody 接收前端传来的 json数据
        packageService.add(pack);
        return Result.success();
    }

    @PutMapping("/update")
    public Result update(@RequestBody Package pack) { // @RequestBody 接收前端传来的 json数据
        packageService.update(pack);
        return Result.success();
    }

    @PutMapping("/updateBatchStatus")
    public Result updateBatchStatus(@RequestBody Map<String, Object> params) {
        List<Integer> ids = (List<Integer>) params.get("ids");
        String state = (String) params.get("state");
        packageService.updateBatchStatus(ids, state);
        return Result.success();
    }

    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) { // @PathVariable 接收前端传来的路径参数
        packageService.deleteById(id);
        return Result.success();
    }

    @DeleteMapping("/deleteBatch")
    public Result deleteBatch(@RequestBody List<Package> list) { // @RequestBodys 接收前端传来的路径参数
        packageService.deleteBatch(list);
        return Result.success();
    }

    @GetMapping("/selectPackage") // 完整的请求路径：http://localhost:8080/package/selectPackage
    public Result selectPackage(Package pack) {
        List<Package> packageList = packageService.selectPackage(pack);
        return Result.success(packageList);
    }

    /**
     * 分页查询
     * pageNum：当前页码
     * pageSize：每页显示条数
     */
    @GetMapping("selectPage")
    public Result selectPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String keyword,  // 新增keyword参数
            @RequestParam(required = false) String state, // 显式接收state参数
            @RequestParam(required = false) String recipientName,
            @RequestParam(required = false) String senderName) {
        Package queryPackage = new Package();
        queryPackage.setState(state);                   // 设置状态
        queryPackage.setKeyword(keyword);               // 设置关键词
        queryPackage.setRecipientName(recipientName);   // 设置收件人姓名
        queryPackage.setSenderName(senderName);   // 设置收件人姓名
        PageInfo<Package> pageInfo = packageService.selectPage(pageNum, pageSize, queryPackage);
        return Result.success(pageInfo);
    }

    /**
     * 导出数据
     * ids: 1, 2, 3
     */
    @GetMapping("/export")
    public void exportData(Package pack, HttpServletResponse response) throws Exception {
        String ids = pack.getIds();
        if (StrUtil.isNotBlank(ids)) {
            String[] idsArr = ids.split(",");
            pack.setIdsArr(idsArr);
        }
        // 拿到所有数据
        List<Package> list = packageService.selectPackage(pack);
        // 构建Writer对象
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 设置中文表头
        writer.addHeaderAlias("trackingNumber", "快递单号");
        writer.addHeaderAlias("packageName", "包裹名称");
        writer.addHeaderAlias("senderName", "寄件人姓名");
        writer.addHeaderAlias("senderPhone", "寄件人联系方式");
        writer.addHeaderAlias("senderAddress", "寄件人地址");
        writer.addHeaderAlias("recipientName", "收件人姓名");
        writer.addHeaderAlias("recipientPhone", "收件人联系方式");
        writer.addHeaderAlias("recipientAddress", "收件人地址");
        writer.addHeaderAlias("courier", "快递公司");
        writer.addHeaderAlias("shippingTime", "发货时间");
        writer.addHeaderAlias("state", "包裹状态");
        writer.addHeaderAlias("packageIntroduction", "包裹备注");

        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);

        // 写出数据到writer
        writer.write(list);
        // 设置输出的文件的名称以及输出流的头信息
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("包裹信息表", StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        // 写出到输出流 并关闭 writer
        ServletOutputStream os = response.getOutputStream();
        writer.flush(os);
        writer.close();
        os.close();
    }

    /**
     * 导入数据
     */
    @PostMapping("/import")
    public Result importData(MultipartFile file) throws Exception {
        // 获取输入流，构建 Reader 对象
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        // 通过 Reader 读取 excel 里面的数据
        reader.addHeaderAlias("快递单号", "trackingNumber" );
        reader.addHeaderAlias("包裹名称", "packageName");
        reader.addHeaderAlias("寄件人姓名", "senderName");
        reader.addHeaderAlias("寄件人联系方式", "senderPhone");
        reader.addHeaderAlias("寄件人地址", "senderAddress");
        reader.addHeaderAlias("收件人姓名", "recipientName");
        reader.addHeaderAlias("收件人联系方式", "recipientPhone");
        reader.addHeaderAlias("收件人地址", "recipientAddress");
        reader.addHeaderAlias("快递公司", "courier");
        reader.addHeaderAlias("发货时间", "shippingTime");
        reader.addHeaderAlias("包裹状态", "state");
        reader.addHeaderAlias("包裹备注", "packageIntroduction");
        List<Package> list = reader.readAll(Package.class);
        // 将数据写到数据库
        for (Package pack : list){
            packageService.add(pack);
        }
        return Result.success();
    }

    @PostMapping("/scan-process")
    public Result processScan(@RequestBody Map<String, String> params) {
        String trackingNumber = params.get("trackingNumber");
        String targetState = params.get("state");

        // 1. 根据单号查询包裹
        Package pkg = packageMapper.selectByTrackingNumber(trackingNumber);
        if (pkg == null) {
            throw new CustomerException("快递单号不存在");
        }

        // 2. 更新状态为待签收
        List<Integer> ids = Collections.singletonList(pkg.getId());
        packageService.updateBatchStatus(ids, targetState);

        // 3. 生成取件码
        String pickupCode = generatorService.generatePickupCode(trackingNumber);

        return Result.success(new HashMap<>() {{
            put("pickupCode", pickupCode);
            put("status", targetState);
        }});
    }

    @GetMapping("/total")
    public Result getPackageTotal() {
        return Result.success(packageService.getPackageTotal());
    }

    @GetMapping("/pendingTotal")
    public Result getPendingPackageTotal() {
        return Result.success(packageService.getPendingPackageTotal());
    }
}
